package com.ansion.basedb.dao.impl;


import androidx.annotation.NonNull;

import com.ansion.basedb.dao.UserLogicDao;
import com.ansion.basedb.dao.helper.UserHelper;
import com.ansion.basedb.dao.model.BaseModel;
import com.ansion.basedb.dao.model.UserModel;
import com.ansion.basedb.database.DBOperateAsyncListener;
import com.ansion.basedb.database.DatabaseOptionType;
import com.ansion.basedb.database.IDatabaseManager;
import com.ansion.basedb.storage.StorageSdk;
import com.ansion.basedb.util.UserBroadcastUtils;
import com.ansion.basetool.preconditions.Preconditions;

import java.util.ArrayList;
import java.util.List;

public abstract class UserLogicDaoImpl implements UserLogicDao {

    @Override
    public UserModel getUser(long uid) {
        return getUserInner(String.valueOf(uid));
    }

    @Override
    public UserModel getUserOnly(long uid) {
        return getUserInner(String.valueOf(uid));
    }

    @Override
    public UserModel getUser(@NonNull String uid) {
        Preconditions.checkNotEmpty(uid);
        return getUserInner(uid);
    }

    @Override
    public UserModel getUserByUcid(String ucid) {
        return getUserInnerUcid(ucid);
    }

    protected UserModel getUserInnerUcid(String ucid) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB) {
            return null;
        }
        String selection = UserModel.kColumnName_UCId + "=?";
        String[] selectionArgs = new String[] {ucid};
        List<UserModel> userList = mainDB.select(UserModel.class, null, selection, selectionArgs, null, null, null,
                null);
        if (userList == null || userList.size() < 1) {
            return null;
        }
        UserModel userModel = userList.get(0);
        if (userModel != null) {
            userModel.decodeExtraData();
        }
        return userModel;
    }

    protected UserModel getUserInner(String uid) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB) {
            return null;
        }
        String selection = UserModel.kColumnName_UserId + "=?";
        String[] selectionArgs = new String[] { uid };
        List<UserModel> userList = mainDB.select(UserModel.class, null, selection, selectionArgs, null, null, null,
                null);
        if (userList == null || userList.size() < 1) {
            return null;
        }
        UserModel userModel = userList.get(0);
        if (userModel != null) {
            userModel.decodeExtraData();
        }
        return userModel;
    }

    @Override
    public List<UserModel> loadAll() {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB) {
            return null;
        }
        List<UserModel> userList = mainDB.select(UserModel.class, null, null, null, null, null, null,
                null);
        if (userList == null || userList.size() < 1) {
            return null;
        }
        for (UserModel userModel : userList) {
            if (userModel != null) {
                userModel.decodeExtraData();
            }
        }
        return userList;
    }

    @Override
    public void saveUser(UserModel user) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB || user == null) {
            return;
        }
        replaceUser(user);
    }

    @Override
	public void saveFromMessage(UserModel user,boolean isVoip) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB || user == null) {
            return;
        }
        user.encodeExtraData();
        mainDB.replace(UserModel.class, user);
        if(!isVoip) {
            UserBroadcastUtils.sendUserModelChangeIntentFromMessage(UserBroadcastUtils.kDAOCategory_RowReplace, user);
        }else{
            UserBroadcastUtils.sendUserModelChangeIntent(UserBroadcastUtils.kDAOCategory_RowReplace, user);
        }
	}

    @Override
    public void saveUsers(List<UserModel> userList) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB || userList == null) {
            return;
        }
        replaceUsers(userList);
    }

    @Override
    public void clearCache() {

    }



    protected void replaceUser(UserModel user){
        replaceUser(user,true);
    }

    protected void replaceUser(UserModel user,boolean dataChange) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB || user == null) {
            return;
        }
        user.encodeExtraData();
        mainDB.replace(UserModel.class, user);
        if(dataChange) {
            UserBroadcastUtils.sendUserModelChangeIntent(UserBroadcastUtils.kDAOCategory_RowReplace, user);
        }
    }

    @Override
    public void saveUserLocal(UserModel user) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB || user == null) {
            return;
        }
        replaceUser(user);
    }

//    @Override
//    public void saveGroupUser(List<GroupUserPB> groupUserPBs) {
//
//    }

    protected void replaceUsers(final List<UserModel> userList) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB || userList == null || userList.size() == 0) {
            return;
        }
        for (UserModel userModel : userList) {
            if (userModel != null) {
                userModel.encodeExtraData();
            }
        }
        mainDB.replace(UserModel.class, userList, new DBOperateAsyncListener() {
            @Override
            public <T extends BaseModel> void onPostExecute(DatabaseOptionType optionType, Class<T> claz, List<T> successModels, List<T> failModels) {
                //todo 待处理
//                UserFTSHelper.updateIndex(ValueSafeTransfer.transformList(userList, (position, userModel) -> ContactBuilder.buildContactInfo(userModel)));
                UserBroadcastUtils.sendUserModelBatchChangeIntent(UserBroadcastUtils.kDAOCategory_RowReplace, userList);
            }
        });

    }

    protected void replaceUsers(final List<UserModel> userList, final UserLogicDao.DBOperationCallback callBack) {
        IDatabaseManager mainDB = StorageSdk.getMainDB();
        if (null == mainDB || userList == null || userList.size() == 0) {
            if (callBack != null) {
                callBack.onFinished();
            }
            return;
        }
        for (UserModel userModel : userList) {
            if (userModel != null) {
                userModel.encodeExtraData();
            }
        }
        mainDB.replace(UserModel.class, userList,new DBOperateAsyncListener() {

			@Override
			public <T extends BaseModel> void onPostExecute(DatabaseOptionType arg0,
					Class<T> arg1, List<T> arg2, List<T> arg3) {
				if(callBack != null){
					callBack.onFinished();
				}
                UserBroadcastUtils.sendUserModelBatchChangeIntent(UserBroadcastUtils.kDAOCategory_RowReplace, userList);
			}
		});

    }


//	@Override
//	public List<UserModel> saveUserFromSimpleCocoAccountPBs(
//			List<BabaAccountPB> simpleCocoAccountPBList, UserLogicDao.DBOperationCallback callBack) {
//        IDatabaseManager mainDB = StorageSdk.getMainDB();
//        if (null == mainDB || simpleCocoAccountPBList == null || simpleCocoAccountPBList.size() == 0) {
//            return null;
//        }
//        List<UserModel> replaceList = new ArrayList<UserModel>();
//        UserModel tmpUser;
//        for (BabaAccountPB simpleCocoAccountPB : simpleCocoAccountPBList) {
//            tmpUser = getUserInner(String.valueOf(simpleCocoAccountPB.uid));
//            if (null != tmpUser) {
//                replaceList.add(updateFromSimple(simpleCocoAccountPB,tmpUser));
//            } else {
//                //反正这里也调不到，这里不用管了
//                replaceList.add(UserHelper.createUserModelFromPB(simpleCocoAccountPB));
//            }
//        }
//        replaceUsers(replaceList);
//		return replaceList;
//	}

//    public UserModel updateFromSimple(BabaAccountPB simpleAccount, UserModel tmpUser) {
//        if (simpleAccount.name != null)
//            tmpUser.setNickName(simpleAccount.name);
//        if (simpleAccount.avatar != null) {
//            tmpUser.setAvatarUrl(simpleAccount.avatar);
//        }
//        if (simpleAccount.whatsUpType != null) {
//            tmpUser.setStatus_type(simpleAccount.whatsUpType);
//        }
//
//        if (tmpUser.getStatus_type() == STATUS_TYPE_CUSTOM) {
//            tmpUser.setNote(simpleAccount.customWhatsUpContent);
//        } else if (tmpUser.getStatus_type() == STATUS_TYPE_SYS) {
//            tmpUser.setNote(simpleAccount.sysWhatsUpNum + "");
//        }
//        if (simpleAccount.countryCode != null)
//            tmpUser.setCountry(simpleAccount.countryCode + "");
//        if (simpleAccount.isVip != null) {
//            tmpUser.setVip(simpleAccount.isVip);
//        }
//        if (simpleAccount.isWallet != null) {
//            tmpUser.setBadgeWallet(simpleAccount.isWallet, simpleAccount.walletExpireTime);
//        }
//
//        if (simpleAccount.ucid != null) {
//            tmpUser.setUcid(simpleAccount.ucid);
//        }
//        return tmpUser;
//    }

	public void deleteAppUser(List<Long> uids) {

        IDatabaseManager mainDB = StorageSdk.getMainDB();
		if (null == mainDB) {
			return;
		}
		String selection = UserModel.kColumnName_UserId + " in ( "+getDeleteList(uids)+" )";
		mainDB.delete(UserModel.class, selection, null);
        UserBroadcastUtils.sendUserModelChangeIntent(UserBroadcastUtils.kDAOCategory_RowRemove,null);
	}

   public void deleteAppUser(long uid) {

       IDatabaseManager mainDB = StorageSdk.getMainDB();
		if (null == mainDB) {
			return;
		}
		String selection = UserModel.kColumnName_UserId + " = " + uid;
		mainDB.delete(UserModel.class, selection, null);
       UserBroadcastUtils.sendUserModelChangeIntent(UserBroadcastUtils.kDAOCategory_RowRemove,null);
	}

	private String getDeleteList(List<Long> uids) {
		StringBuilder deleteSql = new StringBuilder();
		boolean firstFlag = true;
		for (long uid : uids) {
			if (!firstFlag) {
				deleteSql.append(",");
			} else {
				firstFlag = false;
			}
			deleteSql.append("'").append(uid).append("'");
		}
		return deleteSql.toString();
	}

}
